#include "sqliteutil.h"
#include "macro/macro.h"
#include "fileutil.h"

#include <QtSql/QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
#include <QDebug>

QString SqliteUtil::m_dbFile;

void SqliteUtil::setDBFile(const QString &value)
{
    m_dbFile = value;
}

bool SqliteUtil::checkDBFile()
{
    if (FileUtil::fileSize(m_dbFile) > 0) return true;
    FileUtil::createFileDirectory(m_dbFile);
    initTable();
    return false;
}

bool SqliteUtil::initTable()
{
    bool success = false;
    do
    {
        QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", WATER_TABLE_CONNECTIONNAME);
        database.setDatabaseName(m_dbFile);
        if (!database.open())
        {
            qDebug() << "open database error.";
            break;
        }

        QSqlQuery query(database);

        QString sql = QString("create table if not exists %1(Key varchar(32) PRIMARY KEY,Value text)").arg(WATER_TABLE_NAME);
        query.prepare(sql);
        success = query.exec();
        if (!success)
        {
            QSqlError error = query.lastError();
            qDebug() << QString("execute sql[%1] failed, errorType:[%2], driverText:[%3], databaseText:[%4].").arg(sql, QString::number(error.type()), error.driverText(), error.databaseText());
            break;
        }
    } while (0);
    QSqlDatabase::removeDatabase(WATER_TABLE_CONNECTIONNAME);
    return success;
}

QString SqliteUtil::readConfig(const QString &key)
{
    QString content;
    do
    {
        QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", WATER_TABLE_CONNECTIONNAME);
        database.setDatabaseName(m_dbFile);
        if (!database.open())
        {
            qDebug() << "open database error.";
            break;
        }
        QString sql = QString("select Value from %1 where Key='%2'").arg(WATER_TABLE_NAME, key);

        QSqlQuery query(database);
        query.prepare(sql);
        bool success = query.exec();
        if (!success)
        {
            QSqlError error = query.lastError();
            qDebug() << QString("execute sql[%1] failed, errorType:[%2], driverText:[%3], databaseText:[%4].").arg(sql, QString::number(error.type()), error.driverText(), error.databaseText());
            break;
        }
        while(query.next())
        {
            content = query.value(0).toString();
            break;
        }
    } while (0);
    QSqlDatabase::removeDatabase(WATER_TABLE_CONNECTIONNAME);
    return content;
}

QVariantMap SqliteUtil::readConfigs()
{
    QVariantMap contentMap;
    do
    {
        QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", WATER_TABLE_CONNECTIONNAME);
        database.setDatabaseName(m_dbFile);
        if (!database.open())
        {
            qDebug() << "open database error.";
            break;
        }
        QString sql = QString("select Key,Value from %1").arg(WATER_TABLE_NAME);

        QSqlQuery query(database);
        query.prepare(sql);
        bool success = query.exec();
        if (!success)
        {
            QSqlError error = query.lastError();
            qDebug() << QString("execute sql[%1] failed, errorType:[%2], driverText:[%3], databaseText:[%4].").arg(sql, QString::number(error.type()), error.driverText(), error.databaseText());
            break;
        }
        while(query.next())
        {
            QString key = query.value(0).toString();
            QString value = query.value(1).toString();
            contentMap.insert(key, value);
        }
    } while (0);
    QSqlDatabase::removeDatabase(WATER_TABLE_CONNECTIONNAME);
    return contentMap;
}

bool SqliteUtil::saveConfig(const QString &key, const QString &value)
{
//    checkDBFile();

    bool success = false;
    do
    {
        QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", WATER_TABLE_CONNECTIONNAME);
        database.setDatabaseName(m_dbFile);
        if (!database.open())
        {
            qDebug() << "open database error.";
            break;
        }

        QSqlQuery query(database);

        QString updateSql = QString("update %1 set Value='%3' where Key='%2'").arg(WATER_TABLE_NAME, key, value);
        query.prepare(updateSql);
        success = query.exec();
        if (!success)
        {
            QSqlError error = query.lastError();
            qDebug() << QString("execute sql[%1] failed, errorType:[%2], driverText:[%3], databaseText:[%4].").arg(updateSql, QString::number(error.type()), error.driverText(), error.databaseText());
            break;
        }

        QString insertSql = QString("insert or ignore into %1 (Key,Value) values ('%2','%3')").arg(WATER_TABLE_NAME, key, value);
        query.prepare(insertSql);
        success = query.exec();
        if (!success)
        {
            QSqlError error = query.lastError();
            qDebug() << QString("execute sql[%1] failed, errorType:[%2], driverText:[%3], databaseText:[%4].").arg(updateSql, QString::number(error.type()), error.driverText(), error.databaseText());
            break;
        }
    } while (0);
    QSqlDatabase::removeDatabase(WATER_TABLE_CONNECTIONNAME);
    return success;
}

bool SqliteUtil::saveConfigs(const QVariantMap &configs)
{
    bool success = false;
    do
    {
        QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", WATER_TABLE_CONNECTIONNAME);
        database.setDatabaseName(m_dbFile);
        if (!database.open())
        {
            qDebug() << "open database error.";
            break;
        }
        // 开启事务
        database.transaction();

        QVariantMap::const_iterator it;
        for (it = configs.cbegin(); it != configs.cend(); ++it)
        {
            QSqlQuery query(database);

            QString updateSql = QString("update %1 set Value='%3' where Key='%2'").arg(WATER_TABLE_NAME, it.key(), it.value().toString());
            query.prepare(updateSql);
            if (!query.exec())
            {
                QSqlError error = query.lastError();
                qDebug() << QString("execute sql[%1] failed, errorType:[%2], driverText:[%3], databaseText:[%4].").arg(updateSql, QString::number(error.type()), error.driverText(), error.databaseText());
                continue;
            }

            QString insertSql = QString("insert or ignore into %1 (Key,Value) values ('%2','%3')").arg(WATER_TABLE_NAME, it.key(), it.value().toString());
            query.prepare(insertSql);
            if (!query.exec())
            {
                QSqlError error = query.lastError();
                qDebug() << QString("execute sql[%1] failed, errorType:[%2], driverText:[%3], databaseText:[%4].").arg(updateSql, QString::number(error.type()), error.driverText(), error.databaseText());
                continue;
            }
        }
        database.commit();
        success = true;
    } while (0);
    QSqlDatabase::removeDatabase(WATER_TABLE_CONNECTIONNAME);
    return success;
}
